<!--test.vue-->
<template>
  <div class="base-map">
    <!-- <v-chart ref="echarts" class="chart" :option="option" /> -->
    <div
      id="map"
      style="width:100%;height:100%;"
    ></div>
  </div>
</template>

<script>
import { mapState, mapGetters } from "vuex";
import { cloneDeep } from 'lodash'
import { debounce } from "lodash";
import AMapLoader from "@amap/amap-jsapi-loader";
import * as echarts from "echarts";
require("echarts-extension-amap");
import { series, data, dataArr, geoCoordMap } from "./data.js";
console.log("echarts", echarts);
export default {
  name: "BaseMap",
  props: {
    mapConfig: {
      type: Object,
      default: () => {
        const config = {
          option: {
            backgroundColor: 'rgba(225,225,225,0)',
            animation: true,
            series: [],
            amap: {
              maxPitch: 60,
              pitch: 10, //45 俯仰角
              viewMode: "2D",
              zoom: 6, // 7.7
              expandZoomRange: true,
              zooms: [3, 20],
              mapStyle: "amap://styles/dark", //地图主题
              center: [108.95, 34.27], //[108.95, 34.27], //中心点
              rotation: 0, //顺时针旋转角度
              renderOnMoving: true,
              echartsLayerInteractive: true,
            },
            tooltip: {
              trigger: "item",
              triggerOn: "none",
              backgroundColor: "transparent",
              borderColor: "transparent",
              position: function (point, params, dom, rect, size) {
                // 固定在顶部
                // console.log(point, params, dom, rect, size)
                if (
                  point[0] <= 0 ||
                  point[1] <= 0 ||
                  point[0] >= size.viewSize[0] ||
                  point[1] >= size.viewSize[1]
                ) {
                  dom.style.display = "none";
                }
                dom.style.boxShadow = "none";
                return [point[0], point[1]];
              },
              confine: true,
            },
          },
          gaodeInlineConfig: {
            key: "a89fdf4cbc9a5f0884f637b34f1eb246",
            version: "2.0",
            plugins: ["AMap.DistrictSearch", "AMap.CustomLayer"],
            AMapUI: {
              version: "1.1",
              plugins: [],
            },
            show: true
          },
          bubbleConfig: {
            configName: 'bubbleConfig',
            data: ["宝鸡", "延安", "兰州", "郑州", "临汾"],
            show: true,
            sery: {
              type: 'scatter',
              coordinateSystem: 'amap',
              symbolSize: 0,
              data: []
            }
          },
          hotAreaConfig: {
            configName: 'hotAreaConfig',
            provinces: [
              "上海",
              "北京",
              "湖北",
              "湖南",
              "兰州",
              "陕西",
              "河北",
              "江苏",
              "南阳",
            ],
            citys: [],
            districts: [],
            polygonConfig: {
              fillColor: "transparent",
              strokeOpacity: 1,
              fillOpacity: 0.5,
              strokeColor: "#fff",
              strokeWeight: 1,
              strokeStyle: "dashed",
              strokeDasharray: [5, 5],
              // bubble: true // 是否将覆盖物的鼠标或touch等事件冒泡到地图上
            },
            show: true
          },
          breathBubbleConfig: {
            configName: 'breathBubbleConfig',
            show: true,
            name: "上海 Top10",
            type: "effectScatter",
            coordinateSystem: "amap",
            zlevel: 2,
            symbolSize: 15,
            rippleEffect: {
              brushType: "stroke",
              scale: 5,
              color: '#3779fd',
              brushType: 'fill'
            },
            effectType: 'ripple',
            label: {
                show: true,
                position: "bottom",
                formatter: "{b}"

            },
            itemStyle: {
                color: "#3779fd",
            },
            data: [
              {
                name: "西安",
                value: [
                  108.95, 34.27,
                  65
                ]
              }
            ],
            encode: {
              value: 2
            },
          },
          // 飞线
          flylineConfig: {
            configName: 'flylineConfig',
            show: true,
            name: "上海 Top10",
            coordinateSystem: "amap",
            type: "lines",
            zlevel: 1,
            effect: {
              show: true,
              period: 5,
              trailLength: 0.7,
              color: "#2f44c8",
              symbolSize: 4,
              constantSpeed: 100,
            },
            blendMode: 'lighter',
            lineStyle: {
              color: "rgba(47,68,200,0.1)",
              width: 1,
              curveness: 0.2,
              opacity: 0
            },
            data: []
          },
          // 耀斑
          effectScatter: {
            configName: 'effectScatter',
            name: "PM2.5",
            type: "effectScatter",
            coordinateSystem: "amap",
            rippleEffect: {
              brushType: "stroke",
              scale: 5,
              color: 'red',
              brushType: 'fill',
              period: 2
            },
            effectType: 'ripple',
            data: [],
            symbolSize: function (val) {
              return val[2] / 20;
            },
            encode: {
              value: 2
            },
            label: {
              formatter: "{b}",
              position: "right",
              show: false
            },
            itemStyle: {
              color: "red"
            },
            emphasis: {
              label: {
                show: true
              }
            }
          },
          childComponents: [
            {
              name: '气泡层',
              component: 'BubbleConfig',
              show: true
            },
            {
              name: '热力层',
              component: 'HotAreaConfig',
              show: true
            },
            {
              name: '高德在线地图',
              component: 'GaodeInlineConfig',
              show: true
            },
            {
              name: '呼气气泡层',
              component: 'BreathBubbleConfig',
              show: true
            },
            {
              name: '飞线图',
              component: 'FlylineConfig',
              show: true
            }
          ]
        };
        return config;
      },
    },
  },
  computed: {
    ...mapState({
      // projectData: state => state.editor.projectData,
      // activePageUUID: state => state.editor.activePageUUID,
      // activeElementUUID: state => state.editor.activeElementUUID
    }),
    ...mapGetters([
      // 'currentPageIndex',
      // 'activeElementIndex',
      "activeElement",
    ]),
    childComponents(){
      return this.activeElement && JSON.stringify(this.activeElement.propsValue.mapConfig.childComponents) || ''
    }
  },
  watch: {
    'activeElement.propsValue.mapConfig.option.amap.center': {
      handler(val) {
        this.map && val && this.setCenter(val, this.map)
      }
    },
    'activeElement.propsValue.mapConfig.option.amap.zoom': {
      handler(val) {
        const zooms = this.mapConfig.option.amap.zooms
        if(val <= zooms[1] && val >= zooms[0]) {
          this.map && val && this.map.setZoom(val)
        }
      }
    },
    'activeElement.propsValue.mapConfig.option.amap.zooms': {
      handler(newVal, oldVal) {
        console.log(newVal, oldVal)
        if(!newVal || !oldVal) return
        if(newVal[0] !== oldVal[0]) {
          if(newVal[0] > this.mapConfig.option.amap.zoom) {
            this.map && newVal && this.map.setZoomAndCenter(newVal[0], this.mapConfig.option.amap.center)
          }
        }else {
          if(newVal[1] < this.mapConfig.option.amap.zoom) {
            this.map && newVal && this.map.setZoomAndCenter(newVal[1], this.mapConfig.option.amap.center)
          }
        }
      }
    },
    'activeElement.commonStyle.backgroundColor': {
      handler(val) {
        document.getElementsByClassName('amap-layers')[0].style.backgroundColor = val
      }
    },
    childComponents: {
      handler(newVal, oldVal) {
        const _newVal = newVal && JSON.parse(newVal) || []
        const _oldVal = oldVal && JSON.parse(oldVal) || []
        if(!_newVal.length || !_oldVal.length) return
        let tempData = null
        for(let i = 0, len = _newVal.length; i < len; i++) {
          if(_newVal[i].show !== _oldVal[i].show) {
            tempData = _newVal[i]
            break
          }
        }
        if(tempData) {
          this.isShowWho(tempData, true)
        }
        // this.init(true)
      } 
    }
  },
  data() {
    return {
      option: {},
      polygonCache: []
    };
  },
  created() {
    this.loadCss(
      "https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"
    );
    this.loadJs("https://a.amap.com/jsapi_demos/static/geojson/shanghai.js");
    this.loadJs(
      "https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"
    );
    
  },
  mounted() {
    console.log("mounted", this.$refs["echarts"]);
    AMapLoader.load(this.mapConfig.gaodeInlineConfig).then((AMap) => {
      this.init(false)
      this.option = { ...this.mapConfig.option };
      console.log(this.option)
      this.chart = echarts.init(document.getElementById("map"));
      this.chart.setOption(this.option);
      this.map = this.chart.getModel().getComponent("amap").getAMap();
      this.AMap = AMap
      console.log(this.map, this.chart);
      console.log("地图初始化", AMap);
      console.log("地图初始化", this.$refs["echarts"]);
      this.drawBounds(AMap);
      this.drawTooltips(this.mapConfig.bubbleConfig.data, data);
      
    });
  },
  methods: {
    init(isRefresh) {
      console.log(dataArr)
      let sery = cloneDeep(this.mapConfig.bubbleConfig.sery)
      console.log(sery)
      const _data = this.convertData(data, geoCoordMap)
      sery.data = _data
      this.mapConfig.option.series = [sery]
      // 飞线
      this.mapConfig.flylineConfig.data = dataArr
      this.mapConfig.effectScatter.data = _data
      // 气泡
      this.mapConfig.option.tooltip.formatter = this._formatFn
      this.mapConfig.childComponents.forEach(item => {
          this.isShowWho(item, isRefresh)
      })
      
    },
    loadJs(src) {
      let script = document.createElement("script");
      script.type = "text/javascript";
      script.src = src;
      document.getElementsByTagName("head")[0].appendChild(script);
      // 引入成功
      script.onload = function () {
        console.log(src, "js资源已加载成功了");
      };
      // 引入失败
      script.onerror = function () {
        console.log(src, "js资源加载失败了");
      };
    },
    loadCss(url) {
      let css = document.createElement("link");
      css.href = url;
      css.rel = "stylesheet";
      css.type = "text/css";
      document.head.appendChild(css);
    },
    drawTooltips(showNames, data) {
      let showIndexArr = showNames.map((item) => {
        return data.findIndex((dataItem) => dataItem.name === item) || 0;
      });
      var dataIndex = 0;
      console.log(showIndexArr);
      this.chart.dispatchAction({
        type: "showTip",
        seriesIndex: 0,
        dataIndex: showIndexArr[dataIndex],
      });
      this.timer = setInterval(() => {
        dataIndex === showIndexArr.length - 1 ? (dataIndex = 0) : dataIndex++;
        this.chart.dispatchAction({
          type: "showTip",
          seriesIndex: 0,
          dataIndex: showIndexArr[dataIndex],
        });
      }, 3000);
    },
    _formatFn(params) {
      const { name } = params;
      return (
        '<div class="tooltip-class" style="position: relative; z-index: 9999;"><div class="iconclass"><img src="https://img.alicdn.com/tfs/TB1zrmCtXY7gK0jSZKzXXaikpXa-96-96.png"></div><span class="sp-class">' +
        name +
        "</span></div>"
      );
    },
    drawBounds(AMap) {
      let district = null;
      let polygons = [];
      let that = this;
      //加载行政区划插件
      if (!district) {
        //实例化DistrictSearch
        let opts = {
          subdistrict: 0, //获取边界不需要返回下级行政区
          extensions: "all", //返回行政区边界坐标组等具体信息
          level: "district", //查询行政级别为 市
        };
        district = new AMap.DistrictSearch(opts);
      }
      //行政区查询
      // district.setLevel('province')
      let provinces = this.mapConfig.hotAreaConfig.provinces;
      for (let i = 0, len = provinces.length; i < len; i++) {
        that._draw(provinces[i], district, i);
      }
    },
    _draw(provinceName, district, index) {
      let that = this;
      let polygonArr = [];
      district.search(provinceName, (status, result) => {
        that.map.remove(polygonArr); //清除上次结果
        polygonArr = [];
        var bounds = result.districtList[0].boundaries;
        if (bounds) {
          for (let i = 0, l = bounds.length; i < l; i++) {
            //生成行政区划polygon
            let polygon = new AMap.Polygon({...this.mapConfig.hotAreaConfig.polygonConfig, path: bounds[i]});
            polygon.on("mouseover", () => {
              polygon.setOptions({
                fillOpacity: 0.7,
                fillColor: "#ccebc5",
              });
            });
            polygon.on("mouseout", () => {
              polygon.setOptions({
                fillColor: "transparent",
                strokeOpacity: 1,
              });
            });
            polygonArr.push(polygon);
            this.polygonCache.push(polygon)
          }
          
          that.map.add(polygonArr);
          // index === 0 && that.map.setFitView(polygonArr);//视口自适应
        }
      });
    },
    convertData(data, geoCoordMap) {
      var res = [];
      for (var i = 0; i < data.length; i++) {
        var geoCoord = geoCoordMap[data[i].name];
        if (geoCoord) {
          res.push({
            name: data[i].name,
            value: geoCoord.concat(data[i].value)
          });
        }
      }
      return res;
    },
    // 地图中心
    setCenter: debounce((val, map)=>{
      console.log('设置中心', val)
      map.setCenter(val)
    }, 1000),
    // 展示隐藏谁
    isShowWho(data = {}, isRefresh) {
      console.log('isShowWho', data)
      const { show, component } = data
      switch (component) {
        case 'FlylineConfig':
          this.showFlyLine(show, isRefresh)
          break;
        case 'BreathBubbleConfig':
          this.showBreathBubbleConfig(show, isRefresh)
          break;
        case 'GaodeInlineConfig':
          this.showGaodeInlineConfig(show, isRefresh)
          break;
        case 'HotAreaConfig':
          this.showHotAreaConfig(show, isRefresh)
          break;
        case 'BubbleConfig':
          this.showBubbleConfig(show, isRefresh)
          break;
        default:
          break;
      }
      /* this.chartRefresh() */
    },
    // 飞线 + 耀斑
    showFlyLine(isShow, isRefresh) {
      // const { childComponents } = this.mapConfig
      // const componentData = childComponents.find(item => item.component === 'FlylineConfig')
      // const isShow = componentData && componentData.show || false
      console.log(this.mapConfig.option.series)
      if(isShow) {
        const _index = this.mapConfig.option.series.findIndex(item => item.configName === 'flylineConfig')
        console.log(_index, this.mapConfig.flylineConfig)
        _index > -1 ? this.mapConfig.option.series.splice(_index, 1, cloneDeep(this.mapConfig.flylineConfig)) : this.mapConfig.option.series.push(cloneDeep(this.mapConfig.flylineConfig))
        this.mapConfig.option.series.push(this.mapConfig.effectScatter)
        console.log(this.mapConfig.option.series)
      }else {
        this.mapConfig.option.series = this.mapConfig.option.series.filter(item => {
          if(item.configName === 'flylineConfig') {
            item.lineStyle.width = 0
            item.effect.show = false
          }
          if(item.configName !== 'effectScatter') {
            return true
          }
        })
      }
      console.log('showFlyLine', this.mapConfig.option.series)
      isRefresh && this.chartRefresh()
    },
    // 呼吸气泡
    showBreathBubbleConfig(isShow, isRefresh) {
      // const { childComponents } = this.mapConfig
      // const componentData = childComponents.find(item => item.component === 'BreathBubbleConfig')
      // const isShow = componentData && componentData.show || false
      if(isShow) {
        this.mapConfig.option.series.push(this.mapConfig.breathBubbleConfig)
      }else {
        this.mapConfig.option.series = this.mapConfig.option.series.filter(item => {
          return item.configName !== 'breathBubbleConfig'
        })
      }
      isRefresh && this.chartRefresh()
    },
    // 气泡
    showBubbleConfig(isShow, isRefresh) {
      this.timer && clearInterval(this.timer)
      if(isRefresh && isShow) {
        this.drawTooltips(this.mapConfig.bubbleConfig.data, data);
      }else if(isRefresh && !isShow) {
        this.chart.dispatchAction({
            type: 'hideTip'
        })
      }
    },
    // 热力层
    showHotAreaConfig(isShow, isRefresh) {
      if(isRefresh ) {
        this.polygonCache.forEach(polygon => {
          isShow? polygon.show() : polygon.hide()
        })
      }
    },
    // 高德地图是否在线
    showGaodeInlineConfig(isShow, isRefresh) {
      if(isRefresh) {
        if(!isShow) {
          // this.map.destroy()
          console.log(document.getElementsByClassName('amap-layer'))
          document.getElementsByClassName('amap-layer')[0].style.display = 'none'
        }else {
          document.getElementsByClassName('amap-layer')[0].style.display = 'block'
        }
      }
    },
    // echart更新
    chartRefresh() {
      console.log('refresh', this.mapConfig.option)
      console.log(echarts.getInstanceByDom(document.getElementById("map")))
      this.chart.clear()
      this.chart.setOption(this.mapConfig.option, true);
    }
  },
  beforeDestroy() {
    // this.$refs['echarts'] && this.$refs['echarts'].clear();
    this.map &&
    this.map.destroy() &&
    this.map.clearInfoWindow()
    this.chart && this.chart.clear();
    this.timer && clearInterval(this.timer)
    console.info("地图已销毁");
  }
};
</script>

<style lang="scss" scoped>
#map {
  /deep/.tooltip-class {
    position: relative;
    top: -37px;
    left: -25px;
    .iconclass {
      display: inline-block;
      width: 25px;
      height: 25px;
      vertical-align: bottom;
      img {
        width: 100%;
        height: 100%;
      }
      &::after {
        position: relative;
        top: 4px;
        left: -16px;
        display: inline-block;
        content: "o";
        font-weight: bold;
        color: #2f44c8;
        font-size: 10px;
      }
    }
    .sp-class {
      background: #2f44c8;
      color: #fff;
      padding: 5px 10px;
      margin-left: 5px;
      border-radius: 3px;
    }
  }
}
</style>
